/*
 * File:   IntegerIdentifier.java
 * Author: Oleg S. Estekhin
 */
package dht.async;

import java.util.Random;

public final class IntegerIdentifier extends Identifier
{

    private final int length;

    private final int data;

    /**
     * Creates a new random identifier.
     *
     * @param length the identifier length in bytes
     *
     * @return a new random identifier.
     */
    public static Identifier randomIdentifier(int length)
    {
        int m = 1;
        for (int i = 1; i < length; i++)
        {
            m *= 10;
        }
        Random random = new Random();
        return new IntegerIdentifier(length, Math.abs(random.nextInt()) % m);
    }

    /**
     * Creates a new random identifier.
     *
     * @param length the identifier length in bytes
     * @param random the random generator
     *
     * @return a new random identifier.
     */
    public static Identifier randomIdentifier(int length, Random random)
    {
        int m = 1;
        for (int i = 1; i < length; i++)
        {
            m *= 10;
        }
        return new IntegerIdentifier(length, Math.abs(random.nextInt()) % m);
    }


    /**
     * Creates a new <code>IntegerIdentifier</code> object.
     *
     * @param length the identifier length
     * @param data the identifier data.
     */
    public IntegerIdentifier(int length, int data)
    {
        this.length = length;
        this.data = data;
    }


    @Override
    public int getLength()
    {
        return length;
    }

    @Override
    public Identifier getDistance(Identifier identifier)
    {
        if (identifier == null)
        {
            throw new NullPointerException("identifier is null");
        }
        if (!(identifier instanceof IntegerIdentifier))
        {
            throw new ClassCastException();
        }
        IntegerIdentifier id = (IntegerIdentifier) identifier;
        if (length != id.length)
        {
            throw new IllegalArgumentException("invalid identifier length");
        }
        return new IntegerIdentifier(length, Math.abs(data - id.data));
    }

    @Override
    public int getHighestOneBitPosition()
    {
        Integer i = (Integer) data;
        //todo
        return 0;
    }

    @Override
    public int compareTo(Identifier identifier)
    {
        if (identifier == null)
        {
            throw new NullPointerException("identifier is null");
        }
        if (!(identifier instanceof IntegerIdentifier))
        {
            throw new IllegalArgumentException("invalid identifier type");
        }
        IntegerIdentifier id = (IntegerIdentifier) identifier;
        if (length != id.length)
        {
            throw new IllegalArgumentException("invalid identifier length");
        }
        if (data < id.data)
        {
            return -1;
        }
        else if (data == id.data)
        {
            return 0;
        }
        else
        {
            return 1;
        }
    }

    @Override
    public int hashCode()
    {
        return data;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
        {
            return true;
        }
        else if (obj instanceof IntegerIdentifier)
        {
            IntegerIdentifier id = (IntegerIdentifier) obj;
            return data == id.data;
        }
        else
        {
            return false;
        }
    }

    @Override
    public String toString()
    {
        StringBuilder buffer = new StringBuilder(length);
        buffer.append(data);
        while (buffer.length() < length)
        {
            buffer.insert(0, '0');
        }
        return buffer.toString();
    }

}